package com.mrx.pvzcommunity.model;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.List;

@Data
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@ApiModel(value = "响应结果")
public class Result<T> implements Serializable {
    @ApiModelProperty(value = "响应代码", example = "0")
    private int code;
    @ApiModelProperty(value = "额外响应信息", example = "成功")
    private String msg;
    @ApiModelProperty(value = "响应内容", example = "SUCCESS")
    private T data;

    private static final Logger logger = LoggerFactory.getLogger(Result.class);

    /**
     * 使用自定义 code, msg, data 创建一个 Result
     *
     * @param code 响应代码
     * @param msg  响应消息
     * @param data 响应内容
     * @param <T>  数据类型
     * @return Result
     */
    public static <T> Result<T> createResult(int code, String msg, T data) {
        logger.info("创建 Result 对象 -> code: {}, msg: {}, data: {}", code, msg, data);
        return new Result<>(code, msg, data);
    }

    /**
     * 使用已知响应代码, 自定义 msg, data 创建 Result
     *
     * @param code 响应代码
     * @param msg  响应消息
     * @param data 响应内容
     * @param <T>  数据类型
     * @return Result
     * @see Response.Code
     */
    public static <T> Result<T> createResult(Response.Code code, String msg, T data) {
        return createResult(code.code, msg, data);
    }

    /**
     * 使用已知响应代码, 响应代码自带 msg, 自定义 data 创建 Result
     *
     * @param code 响应代码
     * @param data 响应内容
     * @param <T>  数据类型
     * @return Result
     * @see Response.Code
     */
    public static <T> Result<T> createResult(Response.Code code, T data) {
        return createResult(code, code.desc, data);
    }

    /**
     * 使用已知响应代码,响应代码自带 msg, 异常 data 创建 Result
     *
     * @param code 响应代码
     * @param data 响应内容
     * @return Result
     * @see Response.Code
     */
    public static Result<String> createResult(Response.Code code, Throwable data) {
        return createResult(code, code.desc, data.getMessage());
    }

    /**
     * 使用已知响应代码, 响应代码自带 msg, null 的 data 创建 Result
     *
     * @param code 响应代码
     * @return Result
     * @see Response.Code
     */
    public static Result<String> createResult(Response.Code code) {
        return createResult(code, code.desc, null);
    }

    /**
     * 使用 List 数据创建 Result
     *
     * @param data 要创建的 List 数据
     * @param <T>  List 类型
     * @return Result, 如果 List 为空, 就返回 Response.Code.NOT_FOUND. 否则返回 Response.Code.SUCCESS
     * @see Response.Code#NOT_FOUND
     * @see Response.Code#SUCCESS
     */
    public static <T extends List<?>> Result<T> createResult(T data) {
        if (data.isEmpty()) {
            return createResult(Response.Code.NOT_FOUND, data);
        }
        return createResult(Response.Code.SUCCESS, data);
    }

}
